import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @author 35326
 * 2021/3/24 9:34
 * 通道用于源结点与目标节点之间的连接
 *
 * 通道的主要分类：
 * java.nio.channels.Channel接口：
 * 		|--FileChannel
 * 		|--SocketChannel
 * 		|--ServerSocketChannel
 * 		|--DatagramChannel
 *
 *
 * 	获取通道：
 * 	1. 通过支持通道的类提供的getChannel()方法
 * 		FileInputStream/FileOutputStream
 * 		RandomAccessStream
 * 		网络IO：
 * 		Socket
 * 		ServetSocket
 * 		DatagramSocket
 * 2. 在JDK　　１。７中的NIO　２针对各个通道提供了静态方法open()
 *
 * 3. 在JDK 1.7中的NIO.2 的Files工具类的newByteChannel()方法
 *
 * 4。通道之间的数据传输
 * transFrom()
 * transTo()
 */
public class TestChannel {
	@Test
	public void test1(){
	    //1. 利用通道完成文件的复制
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		try {
			fileInputStream = new FileInputStream("1.txt");
			fileOutputStream = new FileOutputStream("2.txt");
			inChannel = fileInputStream.getChannel();
			outChannel = fileOutputStream.getChannel();
			//完成数据的传输
			ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);

			//将通道中的数据存入缓冲区中
			int len=-1;
			while((len=inChannel.read(byteBuffer))!=-1){
				//切换成读取数据的模式
				byteBuffer.flip();
				outChannel.write(byteBuffer);
				byteBuffer.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//将缓冲区中的数据写入通道
			try {
				outChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				inChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fileInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fileOutputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}



	}

	@Test
	/**
	 * 使用内存映射文件
	 * 只有byteBuffer支持
	 */
	public void test2() throws IOException {
		FileChannel inOpen = FileChannel.open(Paths.get("1.txt"), StandardOpenOption.READ);
		FileChannel outOpen = FileChannel.open(Paths.get("3.txt"), StandardOpenOption.READ,StandardOpenOption.WRITE, StandardOpenOption.CREATE);
		//内存映射文件
		MappedByteBuffer map = inOpen.map(FileChannel.MapMode.READ_ONLY, 0, inOpen.size());
		MappedByteBuffer map1 = outOpen.map(FileChannel.MapMode.READ_WRITE, 0, inOpen.size());
		byte[] bytes = new byte[map.limit()];
		map.get(bytes);
		map1.put(bytes);
		inOpen.close();
		outOpen.close();
	}

	@Test
	public void testTransfer() throws IOException{
		FileChannel inChannel = FileChannel.open(Paths.get("D:\\1.mkv"),StandardOpenOption.READ);
		FileChannel outChanner = FileChannel.open(Paths.get("D:/2.mkv"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
		inChannel.transferTo(0,inChannel.size(),outChanner);
		inChannel.close();
		outChanner.close();
	}
}
